﻿using GalaSoft.MvvmLight;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using System.Reflection;

namespace ArchiSimple.Windows
{
    public static class Locator
    {
        static Locator()
        {
            InitKernel();
        }

        /// <summary>
        /// TODO : Make this private.
        /// </summary>
        public static void InitKernel()
        {
        }

        public static string GetLocate(DependencyObject obj)
        {
            return (string)obj.GetValue(LocateProperty);
        }

        public static void SetLocate(DependencyObject obj, string value)
        {
            obj.SetValue(LocateProperty, value);
        }

        // Using a DependencyProperty as the backing store for Locate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LocateProperty =
            DependencyProperty.RegisterAttached("Locate", typeof(string), typeof(Locator), new PropertyMetadata(null, LocateChange));

        public static void LocateChange(object sender, DependencyPropertyChangedEventArgs e)
        {
            var userControl = sender as FrameworkElement;

            if (userControl.DataContext == null)
            {
                var t = ConvertToType(e.NewValue as string);

                if (ViewModelBase.IsInDesignModeStatic)
                {
                    userControl.DataContext = Activator.CreateInstance(t) as ViewModelBase;
                }
                else
                {
                    var constructor = t.GetTypeInfo().DeclaredConstructors.First();

                    var parameters = constructor.GetParameters();

                    List<Object> parametersObjects = new List<object>();

                    foreach (var parameter in parameters)
                    {
                        parametersObjects.Add(Activator.CreateInstance(parameter.ParameterType));
                    }

                    var vm = constructor.Invoke(parametersObjects.ToArray()) as ViewModelBase;

                    vm.Init();

                    userControl.DataContext = vm;
                }
            }
        }

        private static Type ConvertToType(string p)
        {
            if (p.StartsWith("vm:"))
            {
                return Type.GetType("ArchiSimple.Windows.ViewModel." + p.Substring(3));
            }

            return null;
        }

        public static T Locate<T>(object o)
        {
            var parameters = new List<object>();

            if (o != null)
            {
                var dico = new Dictionary<string, object>();
                foreach (var prop in o.GetType().GetRuntimeProperties())
                {
                    dico.Add(prop.Name, prop.GetValue(o, new object[0]));
                }

                foreach (var parameter in typeof(T).GetTypeInfo().DeclaredConstructors.First().GetParameters())
                {
                    if (dico.ContainsKey(parameter.Name))
                    {
                        parameters.Add(dico[parameter.Name]);
                    }
                    else
                    {
                        parameters.Add(Activator.CreateInstance(parameter.ParameterType));
                    }
                }
            }

            return (T)Activator.CreateInstance(typeof(T), parameters.ToArray());
        }
    }
}
